/**
 * 
 */
package com.study.lock;

import java.util.Scanner;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Administrator
 * @date 2019年6月21日
 */
public class LockInterruptiblyDemo {
	// 实例化Lock对象
	Lock lock = new ReentrantLock();

	/**
	 * @param args
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws InterruptedException {
		
		Scanner in = new Scanner(System.in);
		// 实例化本类对象，目的是调用runThread方法
		LockInterruptiblyDemo tl = new LockInterruptiblyDemo();
		// 匿名对象创建线程1，并重写run方法，启动线程
		Thread t0 = new Thread() {
			public void run() {

				tl.runThread(Thread.currentThread());
			}
		};
		// 匿名对象创建线程2，并重写run方法，启动线程
		Thread t1 = new Thread() {
			public void run() {

				tl.runThread(Thread.currentThread());
			}
		};
		System.out.println("请输入等待时间：");
		int time = in.nextInt();
		long timeL = time*1000;
		// 运行t0线程
		t0.start();
		// 等待1秒
		Thread.sleep(1000);
		// 运行t1
		t1.start();
		// 等待线程获锁时间
		Thread.sleep(timeL);
		// t1获取锁失败，中断t1
		t1.interrupt();

	}

	// 线程共同调用方法
	public void runThread(Thread t) {
		System.out.println("线程" + t.getName() + "尝试获取锁");
		// 尝试获取锁，被中断会进入中断异常处理块中
		// 这货没有时间限制的尝试获取锁，和synchronized一样，但是，这货能相应中断，这是synchronized没有的优点，这使得程序在另外的线程没有释放锁时能自定义退出程序。
		//当通过lockInterruptibly()方法获取某个锁时，如果不能获取到，只有进行等待的情况下，是可以响应中断的。(解决死锁)
		//而用synchronized修饰的话，当一个线程处于等待某个锁的状态，是无法被中断的，只有一直等待下去。
		try {
			lock.lockInterruptibly();
		} catch (InterruptedException e1) {
			System.out.println("线程"+t.getName()+"被中断");
			return;
		}
		try {
			System.out.println(t.getName() + "获取锁成功");
			for (int i = 0; i < 5; i++) {
				Thread.sleep(1000);
				System.out.print(t.getName() + "输出：");
				System.out.println(i + "\t");
			}
		} catch (InterruptedException e) {
			System.out.println("线程"+t.getName()+"被中断");
			return;
		} finally {
			lock.unlock();
			System.out.println("线程" + t.getName() + "释放了锁");
		}

	}
}